iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
自我挑戰組

跟 VueJS 認識的30天系列 第 5

[DAY05]跟 Vue.js 認識的30天 - Vue 的屬性綁定

  • 分享至 

  • xImage
  •  

很多時候我們會利用 class 來切換樣式,這時候其實就可以利用 Vue 的指令 v-bind 來動態切換 class

v-bind:class 屬性綁定

物件語法

<!--v-bind:被綁定的HTML Attribute = "Vue使用的資料" -->
<div v-bind:class="{ active: isActive }"></div>

v-bind 指令告訴了 Vue 這一段的 class 屬性要使用到 Vue 實例裡的 data 資料, { active: isActive } ,前面的 active 是 className,而後面的 isActive 是 Vue 實例裡的 data 資料,決定前面的 active 是否要啟用,是 true 就啟用,否則就不啟用。

<div id=app>
  <button type="button" class="btn btn-danger" v-bind:class="{active:isActive}" v-bind:disabled="isDisabled">我是按鈕</button>
</div>

<script>
  const vm = new Vue({
    el:'#app',
    data:{
      isActive: true,
      isDisabled: false,
    }
  })
</script>

https://ithelp.ithome.com.tw/upload/images/20200921/20127553udTLx4B05l.png

可以注意到元素本身有的 class="btn btn-danger" 並不會受後面的 v-bind:class="{active:isActive}" 影響,而是一種共同存在的關係,在渲染過後元素的 class="btn btn-danger 變成了 class="btn btn-danger active"

也可以將整個物件寫入 v-bind 裡,如此一來這個元素就可以擁有這個物件裡值為 trueclassName

<div v-bind:class="objClass"></div>
  <script>
  const vm = new Vue({
    el:'#app',
    data:{
      isActive: false
      objClass:{
        // 前面直接就是 className ,後面的`true`或`false`決定是否啟用這個樣式
        border:true,
        // 如果有 - 就必須使用屬性名稱就必須使用 ''
        'bg-dark':true,
        'text-white':true
      }
    }
  })
  </script>

陣列語法

  <div v-bind:class="[active,right]"></div>

同樣的 v-bind 指令告訴了 Vue 這一段的 class 屬性要使用到 Vue 實例裡的 data 資料,利用陣列語法把要加入的 class 加入進去,加入的方法如下:

const vm = new Vue({
  el:'#app',
  data:{
    // 自訂屬性名稱: 'className'
    active: 'active',
    right: 'btn-white'
  }
})

上面 data 裡的屬性名稱就是在 v-bind:class 中陣列的資料,而屬性值就是它所代表的 class 樣式名稱。

要如何切換樣式呢?可以透過三元表達式來決定這個屬性( class 樣式)是否存在。

<div v-bind:class="[isActive?arrayClassList.right:'']"></div>

<script>
const vm = new Vue({
  el:'#app',
  data:{
    isActive: false
    arrayClassList:{
      right: 'btn-warning'
    }
  }
})
</script>

如果是利用陣列來切換 class 的話,會顯得有點麻煩,如此一來還是得有一筆資料是用來切換,所以我大部分還是會利用物件語法來製作切換效果。

v-bind:style 樣式綁定

物件語法

其實跟上面的 v-bind:class 寫法是很像的。
但是要注意前面的屬性是 CSS 屬性,後面的值是自訂的 JS 屬性名。
而當我們在寫 CSS 屬性名稱時,記得使用小駝峰式或短橫線分隔,例如: fontSize 或是 'font-size'

<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>
  
<script>
const vm = new Vue({
  el:'#app',
  data:{
    activeColor: 'red',
    fontSize: '30px'
  }
})
</script>

比較好的做法是,將這些樣式組成一個單獨的物件後直接代入。

<div v-bind:style="objStyles"></div>
  
<script>
  const vm = new Vue({
    el:'#app',
    data:{
      objStyles:{
        color: 'red',
        fontSize: '20px',
        'background-color': '#000'
      }
    }
  })
</script>

陣列語法

可以利用將多個不同種類的樣式組成不同的物件後,再組合成一個陣列代入 v-bind 裡。

<div v-bind:style="[objStyles, baseStyles]"></div>
  
<script>
  const vm = new Vue({
    el:'#app',
    data:{
      objStyles:{
        color: 'red',
        fontSize: '20px',
        'background-color': '#000'
      },
      baseStyles:{
        border: '2px solid blue',
        padding: '5px 15px'
      }
    }
  })
</script>

如果使用 v-bind:style 綁定樣式的同時,也同時擁有同樣的的 style 屬性,這時候會以 v-bind:style 的資料為主。

<div style="backgroundColor: green !important;" v-bind:style="[objStyles, baseStyles]">我是-v-bind:style(array)</div><script>
  const vm = new Vue({
    el:'#app',
    data:{
      objStyles:{
        color: 'red',
        fontSize: '20px',
        'background-color': '#000'
      },
      baseStyles:{
        border: '2px solid blue',
        padding: '5px 15px'
      }
    }
  })
</script>

https://ithelp.ithome.com.tw/upload/images/20200921/20127553fOzQOX137d.png

上述例子的 <div> 套用的 background-colorv-bind:style 所綁定的資料樣式。

結論:

  • HTML 的任何屬性如果要套用到 Vue 實例 data 資料的話,就必須使用 v-bind 指令,即使是透過 data 資料產生出來的資料也是一樣(例如 v-for 資料要綁到 HTML Attribute 上時也一樣要使用 v-bind 指令)。

  • Vue 提供了 v-bind 指令的縮寫 :,寫法如下:

    <div :class="[isActive?arrayClassList.right:'']"></div>
    <div :style="[objStyles, baseStyles]"></div>
    <img :src="imgUrl"alt="">
    

Demo:[DAY05]跟 Vue.js 認識的30天 - Vue 的屬性綁定

參考資料:

Yes


上一篇
[DAY04]跟 Vue.js 認識的30天 - Vue 的資料偵聽(watch)
下一篇
[DAY06]跟 Vue.js 認識的30天 - Vue 的條件渲染
系列文
跟 VueJS 認識的30天21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言